package craky.componentc;

import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;

import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicToggleButtonUI;

import sun.awt.AppContext;
import sun.swing.SwingUtilities2;
import craky.util.UIUtil;

public class CToggleButtonUI extends BasicToggleButtonUI
{
    private static final Object C_TOGGLE_BUTTON_UI_KEY = new Object();
    
    private int pressMoveX, pressMoveY;
    
    public static ComponentUI createUI(JComponent c)
    {
        AppContext appContext = AppContext.getAppContext();
        CToggleButtonUI cToggleButtonUI = (CToggleButtonUI)appContext.get(C_TOGGLE_BUTTON_UI_KEY);
        
        if(cToggleButtonUI == null)
        {
            cToggleButtonUI = new CToggleButtonUI();
            appContext.put(C_TOGGLE_BUTTON_UI_KEY, cToggleButtonUI);
        }
        
        return cToggleButtonUI;
    }
    
    protected void paintFocus(Graphics g, AbstractButton button, Rectangle viewRect, Rectangle textRect, Rectangle iconRect)
    {
        if(!(button instanceof JCToggleButton))
        {
            super.paintFocus(g, button, viewRect, textRect, iconRect);
        }
    }
    
    protected void paintText(Graphics g, JComponent c, Rectangle textRect, String text)
    {
        if(c instanceof JCToggleButton)
        {
            JCToggleButton button = (JCToggleButton)c;
            ButtonModel model = button.getModel();
            FontMetrics fm = SwingUtilities2.getFontMetrics(c, g);
            int mnemIndex = button.getDisplayedMnemonicIndex();

            if(model.isEnabled())
            {
                g.setColor(button.getForeground());
            }
            else
            {
                g.setColor(button.getDisabledTextColor());
            }
            
            SwingUtilities2.drawStringUnderlineCharAt(c, g, text, mnemIndex, textRect.x + pressMoveX, textRect.y + pressMoveY + fm.getAscent());
        }
        else
        {
            super.paintText(g, c, textRect, text);
        }
    }
    
    protected void paintButtonPressed(Graphics g, AbstractButton b)
    {
        if(b instanceof JCToggleButton && ((JCToggleButton)b).isPaintPressDown())
        {
            pressMoveX = pressMoveY = 1;
        }
        
        super.paintButtonPressed(g, b);
    }
    
    public void paint(Graphics g, JComponent c) 
    {
        pressMoveX = pressMoveY = 0;
        super.paint(g, c);
    }
    
    public void update(Graphics g, JComponent c)
    {
        Graphics2D g2d = (Graphics2D)g;
        Composite oldComposite = g2d.getComposite();
        boolean opaque = c.isOpaque();
        
        if(c instanceof JCToggleButton)
        {
            g2d.setComposite(AlphaComposite.SrcOver.derive(((JCToggleButton)c).getAlpha()));
            opaque = opaque || !((JCToggleButton)c).isImageOnly();
        }
        
        if(opaque)
        {
            g.setColor(c.getBackground());
            g.fillRect(0, 0, c.getWidth(), c.getHeight());
        }
        
        paintBackgroundImage(g, c);
        g2d.setComposite(oldComposite);
        paint(g, c);
    }
    
    protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect)
    {
        Graphics2D g2d = (Graphics2D)g;
        Composite oldComposite = g2d.getComposite();
        
        if(c instanceof JCToggleButton)
        {
            g2d.setComposite(AlphaComposite.SrcOver.derive(((JCToggleButton)c).getAlpha()));
        }
        
        super.paintIcon(g, c, new Rectangle(iconRect.x + pressMoveX, iconRect.y + pressMoveY, iconRect.width, iconRect.height));
        g2d.setComposite(oldComposite);
    }
    
    protected void paintBackgroundImage(Graphics g, JComponent c)
    {
        if(c instanceof JCToggleButton)
        {
            JCToggleButton button = (JCToggleButton)c;
            ButtonModel model = button.getModel();
            Image image = button.getImage();
            Image tempImage = null;
            
            if(image == null)
            {
                return;
            }
            
            if(!model.isEnabled())
            {
                tempImage = model.isSelected()? button.getDisabledSelectedImage(): button.getDisabledImage();
            }
            else if(model.isPressed() && model.isArmed())
            {
                tempImage = button.getPressedImage();
                
                if(tempImage == null)
                {
                    tempImage = button.getSelectedImage();
                }
            }
            else if(model.isSelected())
            {
                if(button.isRolloverEnabled() && model.isRollover())
                {
                    tempImage = button.getRolloverSelectedImage();
                    
                    if(tempImage == null)
                    {
                        tempImage = button.getSelectedImage();
                    }
                }
                else
                {
                    tempImage = button.getSelectedImage();
                }
            }
            else if(button.isRolloverEnabled() && model.isRollover())
            {
                tempImage = button.getRolloverImage();
            }
            
            if(tempImage != null)
            {
                image = tempImage;
            }
            
            Rectangle paintRect = new Rectangle(0, 0, button.getWidth(), button.getHeight());
            UIUtil.paintImage(g, image, button.getImageInsets(), paintRect, button);
        }
    }
    
    protected void installDefaults(AbstractButton b)
    {}
    
    protected void uninstallDefaults(AbstractButton b)
    {}
}